package ooo.reindeer.cedf;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import ooo.reindeer.commons.utils.SerialNumberUtil;

import java.io.IOException;


public class Event<V> {

    private static ObjectMapper mapper = new ObjectMapper();

    private String id;
    private String type;



    static{
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
        mapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES,false);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
    }

//    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "@C")
    private Object data;

    public Event(String type) {
        this(type, null);
    }

    public Event(String type, Object data) {
        this.id = SerialNumberUtil.getSerialNumber();
        this.type = type;
        this.data = data;

    }

    public String getId() {
        return id;
    }

    public String getType() {
        return type;
    }

    public  <T>T getData() {
        return (T) data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String toString() {
        try {
            return mapper.writeValueAsString(this);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public Event clone() {
        try {
            return mapper.readValue(this.toString(), Event.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Event fromString(String json) {
        try {
            return mapper.readValue(json, Event.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    @JsonCreator
    private Event(@JsonProperty("id") String id, @JsonProperty("type") String type, @JsonProperty("data") Object data) {
        this.id = id;
        this.type = type;
        this.data = data;
    }

}
